package com.maijinjie.common.upload;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.codehaus.jackson.map.ObjectMapper;

import com.maijinjie.common.upload.bean.FileVo;
import com.maijinjie.common.util.DateUtil;

/**
 * 文件上传Servlet
 * 
 * @version 1.0
 * @author GhostarX ( 王欣逸 ) 100992995@qq.com &copy;广州迈今捷信息科技有限公司
 */
public class FileUploadServlet extends HttpServlet {
	private static String root = "static/upload/";
	private static String applicationContextPath = "";
	private static String applicationPath="";
	private static String requestPath = "";
	
	private static Map<String,FileUploadHandler> handlerMap = new HashMap<String,FileUploadHandler>();
	@Override
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		// 适应不同操作系统
		applicationContextPath = config.getServletContext().getRealPath("/");		
		if (!(applicationContextPath.lastIndexOf(applicationContextPath
				.length()) == File.separatorChar)) {
			applicationContextPath += File.separator;
		}
		applicationPath = config.getServletContext().getContextPath();
		root = root.replace("//", File.separator);
		
		//初始化上传处理的handler
		handlerMap.put("singlePic", new SinglePicFileUploadHandler());
		handlerMap.put("editorPic", new EditorPicFileUploadHandler());
		handlerMap.put("singleFile", new SingleFileUploadHandler());
		
		requestPath = config.getServletContext().getContextPath();
	}

	/**
	 * 上传组件入口
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		
		//进入的参数
		Map<String,String> parameterMap = new HashMap<String,String>();
		
		FileUploadHandler handler = null;
		
		// 返回的信息
		Map<String, Object> returnMessageMap = new LinkedHashMap<String, Object>();

		DiskFileItemFactory factory = new DiskFileItemFactory();
		ServletContext servletContext = this.getServletConfig()
				.getServletContext();
		File repository = (File) servletContext
				.getAttribute("javax.servlet.context.tempdir");
		((DiskFileItemFactory) factory).setRepository(repository);
		ServletFileUpload upload = new ServletFileUpload(factory);

		// 判断是否是文件上传的请求
		if (ServletFileUpload.isMultipartContent(request)) {
			try {
				List<FileItem> items = upload.parseRequest(request);
				List<FileVo> files = new ArrayList<FileVo>();
				String handleType = "";
				if (items != null) {
					//先处理非文件上传的参数
					for (FileItem item : items) {
						if (item.isFormField()) {
							if (item.getFieldName() != null) {
								parameterMap.put(item.getFieldName(), item.getString());
							}
						} 
					}
					
					//从url中获取handleType的参数
					if(parameterMap.get("handleType") == null){
						parameterMap.put("handleType", request.getRequestURI().toString().replace("/upload/", ""));
					}
					
					
					
					handleType = parameterMap.get("handleType");
					if(handleType != null){
						handler = handlerMap.get(handleType);
					}
					
					if(handler == null){
						handler = handlerMap.get("singlePic");
					}
					
					//再处理文件上传的参数
					for(FileItem item : items){
						if (!item.isFormField()) {
							FileVo vo = new FileVo();
							String fileName = item.getName();
							String prefix = "";
							if (fileName.contains(".")) {
								prefix = fileName.substring(fileName
										.lastIndexOf(".") + 1);
							}
							//产生随机文件名
							vo.setName(UUID.randomUUID() + "." + prefix);
							vo.setRealName(item.getName());
							vo.setSize(item.getSize());
							vo.setType(prefix);
							vo.setUrl(getFileUrlPath(request,vo.getName(),handler));
							vo.setRealPath(getFilePath(vo.getName(),handler));
							//把文件保存到相应位置
							FileOutputStream fos = new FileOutputStream(vo.getRealPath());
							InputStream is = item.getInputStream();
							byte[] buffer = new byte[1024];
							int len = 0;
							while ((len = is.read(buffer, 0, buffer.length)) != -1) {
								fos.write(buffer, 0, len);
							}
							fos.flush();
							fos.close();
							item.delete();
							files.add(vo);
						}
					}
				}
				//通过参数handleType 获取对上传的文件和返回信息再处理的Handler				
				if(files.size()>0){					
					handler.handleUploadFile(parameterMap, returnMessageMap, files);
				}
			} catch (Exception e) {
				e.printStackTrace();				
				returnMessageMap.put("errorMsg", e.getMessage());
			}
		}

		//把返回信息以Json 的格式返回到界面
		if (returnMessageMap.size() > 0) {
			ObjectMapper mapper = new ObjectMapper();
			response.getWriter().write(
					mapper.writeValueAsString(returnMessageMap));
			response.getWriter().flush();
		}

	}

	private String getFileUrlPath(HttpServletRequest request, String name, FileUploadHandler handler) {
		return request.getRequestURL().toString().replace(request.getRequestURI(), "")+"/"+root +handler.returnFileUploadPlace() + DateUtil.getCurrDateStr("yyyy-MM-dd") +"/"+ applicationPath+name;
	}

	/**
	 * 获取文件保存的绝对位置
	 * 
	 * @param root
	 * @param name
	 * @param handler 
	 * @param request
	 * @return
	 */
	private String getFilePath(String name, FileUploadHandler handler) {
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
		File folder = new File(applicationContextPath + root
				+handler.returnFileUploadPlace() + sf.format(new Date()));
		if (!folder.exists()) {
			folder.mkdir();
		} else if (!folder.isDirectory()) {
			folder.delete();
			folder.mkdir();
		}
		return folder + File.separator + name;
	}

}